<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PCAP流量分析平台</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/luxon@3.3.0/build/global/luxon.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1/dist/chartjs-adapter-luxon.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
            color: #333;
        }
        .container {
            max-width: 1400px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        header {
            background: linear-gradient(135deg, #2c3e50, #34495e);
            color: white;
            padding: 30px;
            text-align: center;
        }
        h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        .subtitle {
            font-size: 1.1em;
            opacity: 0.8;
        }
        .main-content {
            display: grid;
            grid-template-columns: 350px 1fr;
            min-height: 600px;
        }
        .sidebar {
            background: #f8f9fa;
            border-right: 1px solid #e9ecef;
            padding: 25px;
        }
        .dashboard {
            padding: 25px;
            display: none;
        }
        .upload-section {
            margin-bottom: 30px;
        }
        .file-input-container {
            position: relative;
            margin-bottom: 15px;
        }
        .file-input {
            width: 100%;
            padding: 12px;
            border: 2px dashed #dee2e6;
            border-radius: 8px;
            background: white;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        .file-input:hover {
            border-color: #667eea;
            background: #f8f9ff;
        }
        .controls {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        button {
            padding: 12px 20px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 600;
            transition: all 0.3s ease;
            font-size: 14px;
        }
        .btn-primary {
            background: #667eea;
            color: white;
        }
        .btn-primary:hover {
            background: #5a6fd8;
            transform: translateY(-2px);
        }
        .btn-secondary {
            background: #6c757d;
            color: white;
        }
        .btn-secondary:hover {
            background: #5a6268;
        }
        .btn-success {
            background: #28a745;
            color: white;
        }
        .btn-success:hover {
            background: #218838;
        }
        .btn-danger {
            background: #dc3545;
            color: white;
        }
        .btn-danger:hover {
            background: #c82333;
        }
        .results-list {
            max-height: 400px;
            overflow-y: auto;
            border: 1px solid #e9ecef;
            border-radius: 8px;
            background: white;
        }
        .result-item {
            padding: 15px;
            border-bottom: 1px solid #f1f1f1;
            cursor: pointer;
            transition: all 0.2s ease;
        }
        .result-item:hover {
            background: #f8f9ff;
        }
        .result-item.active {
            background: #e3f2fd;
            border-left: 4px solid #2196f3;
        }
        .result-item:last-child {
            border-bottom: none;
        }
        .result-filename {
            font-weight: 600;
            margin-bottom: 5px;
            color: #2c3e50;
        }
        .result-meta {
            font-size: 0.85em;
            color: #6c757d;
        }
        .result-stats {
            display: flex;
            gap: 10px;
            margin-top: 5px;
            font-size: 0.8em;
        }
        .stat-badge {
            background: #e9ecef;
            padding: 2px 8px;
            border-radius: 12px;
            color: #495057;
        }
        .card {
            background: white;
            border-radius: 12px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.08);
            padding: 25px;
            border: 1px solid #e9ecef;
            margin-bottom: 25px;
        }
        .card h3 {
            color: #2c3e50;
            margin-bottom: 15px;
            font-size: 1.3em;
            border-bottom: 2px solid #667eea;
            padding-bottom: 8px;
        }
        .stat-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
        }
        .stat-item {
            text-align: center;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }
        .stat-value {
            font-size: 2em;
            font-weight: bold;
            color: #667eea;
            margin-bottom: 5px;
        }
        .stat-label {
            font-size: 0.9em;
            color: #6c757d;
        }
        .chart-container {
            position: relative;
            height: 300px;
            margin-top: 15px;
        }
        .chart-row {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 25px;
            margin-bottom: 25px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 15px;
        }
        th, td {
            padding: 12px 15px;
            text-align: left;
            border-bottom: 1px solid #e9ecef;
        }
        th {
            background: #f8f9fa;
            font-weight: 600;
            color: #2c3e50;
        }
        tr:hover {
            background: #f8f9ff;
        }
        .loading {
            display: none;
            text-align: center;
            padding: 40px;
        }
        .spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #667eea;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 2s linear infinite;
            margin: 0 auto 20px;
        }
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .error {
            color: #dc3545;
            background: #f8d7da;
            padding: 15px;
            border-radius: 8px;
            margin: 15px 0;
            display: none;
        }
        .success {
            color: #155724;
            background: #d4edda;
            padding: 15px;
            border-radius: 8px;
            margin: 15px 0;
            display: none;
        }
        .time-range {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .time-range div {
            margin: 8px 0;
            font-size: 1.1em;
        }
        .empty-state {
            text-align: center;
            padding: 40px 20px;
            color: #6c757d;
        }
        .empty-state i {
            font-size: 3em;
            margin-bottom: 15px;
            opacity: 0.5;
        }
        .section-title {
            font-size: 1.1em;
            font-weight: 600;
            margin-bottom: 15px;
            color: #2c3e50;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .api-status {
            padding: 8px 12px;
            border-radius: 20px;
            font-size: 0.8em;
            font-weight: 600;
            margin-top: 10px;
        }
        .status-online {
            background: #d4edda;
            color: #155724;
        }
        .status-offline {
            background: #f8d7da;
            color: #721c24;
        }
        .progress-bar {
            width: 100%;
            height: 6px;
            background: #e9ecef;
            border-radius: 3px;
            margin-top: 10px;
            overflow: hidden;
        }
        .progress-fill {
            height: 100%;
            background: #667eea;
            width: 0%;
            transition: width 0.3s ease;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>🕵️ PCAP流量分析平台</h1>
            <div class="subtitle">专业级网络流量分析与可视化</div>
        </header>

        <div class="main-content">
            <!-- 侧边栏 -->
            <div class="sidebar">
                <div class="upload-section">
                    <div class="section-title">📁 文件上传</div>
                    <div class="file-input-container">
                        <input type="file" id="pcapFile" class="file-input" accept=".pcap,.pcapng">
                        <div class="progress-bar">
                            <div class="progress-fill" id="uploadProgress"></div>
                        </div>
                    </div>
                    <div class="controls">
                        <button class="btn-primary" onclick="uploadPcap()" id="uploadBtn">
                            上传并解析
                        </button>
                        <button class="btn-secondary" onclick="clearAllResults()">
                            清空所有记录
                        </button>
                    </div>
                    <div id="uploadStatus"></div>
                </div>

                <div class="section-title">📊 分析历史</div>
                <button class="btn-secondary" onclick="loadResults()" style="margin-bottom: 15px;">
                    刷新列表
                </button>
                <div id="resultsList" class="results-list">
                    <div class="empty-state">
                        <div>📋</div>
                        <div>暂无分析记录</div>
                        <div style="font-size: 0.9em; margin-top: 10px;">上传PCAP文件开始分析</div>
                    </div>
                </div>

                <div id="apiStatus" class="api-status status-offline">
                    🔴 服务未连接
                </div>
            </div>

            <!-- 主内容区 -->
            <div class="dashboard" id="dashboard">
                <!-- 时间范围概览 -->
                <div class="card">
                    <h3>📅 分析概览</h3>
                    <div class="time-range" id="timeRange">
                        <div>请选择左侧的分析记录查看详情</div>
                    </div>
                </div>

                <!-- 基础统计 -->
                <div class="card">
                    <h3>📈 基础统计</h3>
                    <div class="stat-grid" id="basicStats">
                        <div class="empty-state">
                            <div>📊</div>
                            <div>暂无数据</div>
                        </div>
                    </div>
                </div>

                <!-- 图表行 -->
                <div class="chart-row">
                    <!-- 请求方法分布 -->
                    <div class="card">
                        <h3>🔧 请求方法分布</h3>
                        <div class="chart-container">
                            <canvas id="methodChart"></canvas>
                        </div>
                    </div>

                    <!-- 状态码分布 -->
                    <div class="card">
                        <h3>🎯 状态码分布</h3>
                        <div class="chart-container">
                            <canvas id="statusChart"></canvas>
                        </div>
                    </div>
                </div>

                <!-- 流量时间分布 -->
                <div class="card">
                    <h3>⏰ 流量时间分布</h3>
                    <div class="chart-container">
                        <canvas id="timeChart"></canvas>
                    </div>
                </div>

                <!-- 第二图表行 -->
                <div class="chart-row">
                    <!-- 客户端IP分析 -->
                    <div class="card">
                        <h3>🌐 客户端IP分析</h3>
                        <div style="max-height: 400px; overflow-y: auto;">
                            <table>
                                <thead>
                                    <tr>
                                        <th>IP地址</th>
                                        <th>请求数</th>
                                        <th>占比</th>
                                    </tr>
                                </thead>
                                <tbody id="ipTableBody">
                                    <tr>
                                        <td colspan="3" style="text-align: center; color: #6c757d;">
                                            暂无数据
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>

                    <!-- 用户代理分析 -->
                    <div class="card">
                        <h3>🤖 用户代理分析</h3>
                        <div style="max-height: 400px; overflow-y: auto;">
                            <table>
                                <thead>
                                    <tr>
                                        <th>User Agent</th>
                                        <th>请求数</th>
                                        <th>占比</th>
                                    </tr>
                                </thead>
                                <tbody id="userAgentTableBody">
                                    <tr>
                                        <td colspan="3" style="text-align: center; color: #6c757d;">
                                            暂无数据
                                        </td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>

                <!-- 请求路径分析 -->
                <div class="card">
                    <h3>🛣️ 热门请求路径</h3>
                    <div style="max-height: 500px; overflow-y: auto;">
                        <table>
                            <thead>
                                <tr>
                                    <th>请求路径</th>
                                    <th>请求数</th>
                                    <th>主要方法</th>
                                    <th>占比</th>
                                </tr>
                            </thead>
                            <tbody id="pathTableBody">
                                <tr>
                                    <td colspan="4" style="text-align: center; color: #6c757d;">
                                        暂无数据
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>

                <!-- 控制按钮 -->
                <div class="controls" style="flex-direction: row; justify-content: flex-end; margin-top: 20px;">
                    <button class="btn-success" onclick="exportReport()" id="exportBtn" disabled>
                        导出报告
                    </button>
                    <button class="btn-danger" onclick="deleteCurrentResult()" id="deleteBtn" disabled>
                        删除当前
                    </button>
                </div>
            </div>
        </div>

        <div class="loading" id="loading">
            <div class="spinner"></div>
            <p>正在分析PCAP文件，请稍候...</p>
            <p style="font-size: 0.9em; color: #6c757d;" id="loadingDetail"></p>
        </div>
    </div>

    <script>
        // 配置
        const CONFIG = {
            API_BASE: 'http://localhost:3000/api',
            MAX_FILE_SIZE: 100 * 1024 * 1024, // 100MB
            AUTO_REFRESH: true
        };

        // 状态管理
        let state = {
            currentResult: null,
            results: [],
            charts: {},
            apiOnline: false
        };

        // DOM 元素
        const elements = {
            pcapFile: document.getElementById('pcapFile'),
            uploadBtn: document.getElementById('uploadBtn'),
            uploadStatus: document.getElementById('uploadStatus'),
            uploadProgress: document.getElementById('uploadProgress'),
            resultsList: document.getElementById('resultsList'),
            dashboard: document.getElementById('dashboard'),
            loading: document.getElementById('loading'),
            loadingDetail: document.getElementById('loadingDetail'),
            apiStatus: document.getElementById('apiStatus'),
            exportBtn: document.getElementById('exportBtn'),
            deleteBtn: document.getElementById('deleteBtn')
        };

        // 初始化
        document.addEventListener('DOMContentLoaded', function() {
            checkAPIStatus();
            loadResults();
            
            // 设置自动刷新
            if (CONFIG.AUTO_REFRESH) {
                setInterval(checkAPIStatus, 30000); // 每30秒检查一次
            }

            // 文件选择事件
            elements.pcapFile.addEventListener('change', function(e) {
                const file = e.target.files[0];
                if (file && file.size > CONFIG.MAX_FILE_SIZE) {
                    showError(`文件大小超过限制 (最大 ${CONFIG.MAX_FILE_SIZE / 1024 / 1024}MB)`);
                    e.target.value = '';
                }
            });
        });

        // 检查API状态
        async function checkAPIStatus() {
            try {
                const response = await fetch(`${CONFIG.API_BASE}/results`, {
                    method: 'GET',
                    signal: AbortSignal.timeout(5000)
                });
                
                if (response.ok) {
                    state.apiOnline = true;
                    elements.apiStatus.textContent = '🟢 服务已连接';
                    elements.apiStatus.className = 'api-status status-online';
                } else {
                    throw new Error('API响应异常');
                }
            } catch (error) {
                state.apiOnline = false;
                elements.apiStatus.textContent = '🔴 服务未连接';
                elements.apiStatus.className = 'api-status status-offline';
            }
        }

        // 上传PCAP文件
        async function uploadPcap() {
            if (!state.apiOnline) {
                showError('解析服务未连接，请确保Node.js服务正在运行');
                return;
            }

            const file = elements.pcapFile.files[0];
            if (!file) {
                showError('请选择PCAP文件');
                return;
            }

            showLoading(true, '准备上传文件...');
            elements.uploadBtn.disabled = true;

            const formData = new FormData();
            formData.append('pcapFile', file);

            try {
                // 模拟上传进度
                simulateUploadProgress();
                
                const response = await fetch(`${CONFIG.API_BASE}/analyze`, {
                    method: 'POST',
                    body: formData
                });

                const result = await response.json();
                
                if (result.success) {
                    showSuccess(result.message);
                    elements.pcapFile.value = '';
                    await loadResults();
                    
                    // 自动加载最新结果
                    if (result.fileId) {
                        setTimeout(() => loadAnalysisResult(result.fileId), 500);
                    }
                } else {
                    throw new Error(result.error || '解析失败');
                }
            } catch (error) {
                showError(`上传失败: ${error.message}`);
            } finally {
                showLoading(false);
                elements.uploadBtn.disabled = false;
                elements.uploadProgress.style.width = '0%';
            }
        }

        // 模拟上传进度
        function simulateUploadProgress() {
            let progress = 0;
            const interval = setInterval(() => {
                progress += Math.random() * 10;
                if (progress >= 90) {
                    clearInterval(interval);
                    elements.uploadProgress.style.width = '90%';
                } else {
                    elements.uploadProgress.style.width = progress + '%';
                }
            }, 200);
        }

        // 加载分析结果列表
        async function loadResults() {
            if (!state.apiOnline) return;

            try {
                const response = await fetch(`${CONFIG.API_BASE}/results`);
                state.results = await response.json();
                renderResultsList();
            } catch (error) {
                console.error('加载结果列表失败:', error);
            }
        }

        // 渲染结果列表
        function renderResultsList() {
            const listDiv = elements.resultsList;
            
            if (state.results.length === 0) {
                listDiv.innerHTML = `
                    <div class="empty-state">
                        <div>📋</div>
                        <div>暂无分析记录</div>
                        <div style="font-size: 0.9em; margin-top: 10px;">上传PCAP文件开始分析</div>
                    </div>
                `;
                return;
            }

            listDiv.innerHTML = state.results.map(result => `
                <div class="result-item ${state.currentResult?.id === result.id ? 'active' : ''}" 
                     onclick="loadAnalysisResult('${result.id}')">
                    <div class="result-filename" title="${result.filename}">
                        ${truncateText(result.filename, 30)}
                    </div>
                    <div class="result-meta">
                        上传时间: ${new Date(result.uploadTime).toLocaleString()}
                    </div>
                    <div class="result-stats">
                        <span class="stat-badge">📦 ${result.stats.totalPackets} 包</span>
                        <span class="stat-badge">🌐 ${result.stats.totalRequests} 请求</span>
                    </div>
                </div>
            `).join('');
        }

        // 加载具体分析结果
        async function loadAnalysisResult(fileId) {
            if (!state.apiOnline) return;

            showLoading(true, '加载分析结果...');

            try {
                const response = await fetch(`${CONFIG.API_BASE}/results/${fileId}`);
                const result = await response.json();
                
                state.currentResult = result;
                renderResultsList(); // 更新激活状态
                updateDashboard(result.analysis);
                showDashboard();
                
                elements.exportBtn.disabled = false;
                elements.deleteBtn.disabled = false;
                
            } catch (error) {
                showError(`加载分析结果失败: ${error.message}`);
            } finally {
                showLoading(false);
            }
        }

        // 更新仪表板
        function updateDashboard(analysisData) {
            if (!analysisData) return;

            updateTimeRange(analysisData.basicStats);
            updateBasicStats(analysisData);
            updateCharts(analysisData);
            updateTables(analysisData);
        }

        // 更新时间范围显示
        function updateTimeRange(stats) {
            const timeRangeDiv = document.getElementById('timeRange');
            
            if (stats.timeRange.start && stats.timeRange.end) {
                const startStr = new Date(stats.timeRange.start).toLocaleString();
                const endStr = new Date(stats.timeRange.end).toLocaleString();
                const duration = Math.round((new Date(stats.timeRange.end) - new Date(stats.timeRange.start)) / 1000 / 60);
                
                timeRangeDiv.innerHTML = `
                    <div><strong>文件名称:</strong> ${state.currentResult.filename}</div>
                    <div><strong>开始时间:</strong> ${startStr}</div>
                    <div><strong>结束时间:</strong> ${endStr}</div>
                    <div><strong>监控时长:</strong> ${duration} 分钟</div>
                    <div><strong>分析时间:</strong> ${new Date(state.currentResult.uploadTime).toLocaleString()}</div>
                `;
            }
        }

        // 更新基础统计
        function updateBasicStats(analysisData) {
            const basicStatsDiv = document.getElementById('basicStats');
            const stats = analysisData.basicStats;

            basicStatsDiv.innerHTML = `
                <div class="stat-item">
                    <div class="stat-value">${stats.totalPackets?.toLocaleString() || '0'}</div>
                    <div class="stat-label">总数据包</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value">${stats.totalRequests?.toLocaleString() || '0'}</div>
                    <div class="stat-label">HTTP请求</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value">${Object.keys(analysisData.clientIPs || {}).length}</div>
                    <div class="stat-label">独立IP</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value">${Object.keys(analysisData.methods || {}).length}</div>
                    <div class="stat-label">请求方法</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value">${Object.keys(analysisData.statusCodes || {}).length}</div>
                    <div class="stat-label">状态码</div>
                </div>
                <div class="stat-item">
                    <div class="stat-value">${Object.keys(analysisData.userAgents || {}).length}</div>
                    <div class="stat-label">User Agent</div>
                </div>
            `;
        }

        // 更新图表
        function updateCharts(analysisData) {
            updateMethodChart(analysisData.methods);
            updateStatusChart(analysisData.statusCodes);
            updateTimeChart(analysisData.hourlyDistribution);
        }

        // 更新请求方法图表
        function updateMethodChart(methodsData) {
            const ctx = document.getElementById('methodChart').getContext('2d');
            
            if (state.charts.methodChart) {
                state.charts.methodChart.destroy();
            }

            if (!methodsData || Object.keys(methodsData).length === 0) {
                return;
            }

            const labels = Object.keys(methodsData);
            const data = Object.values(methodsData);
            const colors = ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF', '#FF9F40'];

            state.charts.methodChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: labels,
                    datasets: [{
                        data: data,
                        backgroundColor: colors,
                        borderWidth: 2,
                        borderColor: '#fff'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'bottom'
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    const total = context.dataset.data.reduce((a, b) => a + b, 0);
                                    const percentage = ((context.parsed / total) * 100).toFixed(1);
                                    return `${context.label}: ${context.parsed} (${percentage}%)`;
                                }
                            }
                        }
                    }
                }
            });
        }

        // 更新状态码图表
        function updateStatusChart(statusCodesData) {
            const ctx = document.getElementById('statusChart').getContext('2d');
            
            if (state.charts.statusChart) {
                state.charts.statusChart.destroy();
            }

            if (!statusCodesData || Object.keys(statusCodesData).length === 0) {
                return;
            }

            // 按状态码分组
            const statusGroups = {
                '2xx成功': 0,
                '3xx重定向': 0,
                '4xx客户端错误': 0,
                '5xx服务端错误': 0
            };

            Object.entries(statusCodesData).forEach(([code, count]) => {
                const firstDigit = code.charAt(0);
                statusGroups[firstDigit + 'xx' + (firstDigit === '2' ? '成功' : firstDigit === '3' ? '重定向' : firstDigit === '4' ? '客户端错误' : '服务端错误')] += count;
            });

            const labels = Object.keys(statusGroups);
            const data = Object.values(statusGroups);
            const colors = ['#28a745', '#17a2b8', '#ffc107', '#dc3545'];

            state.charts.statusChart = new Chart(ctx, {
                type: 'pie',
                data: {
                    labels: labels,
                    datasets: [{
                        data: data,
                        backgroundColor: colors,
                        borderWidth: 2,
                        borderColor: '#fff'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: {
                            position: 'bottom'
                        }
                    }
                }
            });
        }

        // 更新时间分布图表
        function updateTimeChart(hourlyData) {
            const ctx = document.getElementById('timeChart').getContext('2d');
            
            if (state.charts.timeChart) {
                state.charts.timeChart.destroy();
            }

            if (!hourlyData || hourlyData.length === 0) {
                return;
            }

            const labels = hourlyData.map(item => `${item.hour.toString().padStart(2, '0')}:00`);
            const data = hourlyData.map(item => item.count);

            state.charts.timeChart = new Chart(ctx, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: [{
                        label: '请求数量',
                        data: data,
                        borderColor: '#667eea',
                        backgroundColor: 'rgba(102, 126, 234, 0.1)',
                        borderWidth: 3,
                        fill: true,
                        tension: 0.4,
                        pointBackgroundColor: '#667eea',
                        pointBorderColor: '#fff',
                        pointBorderWidth: 2,
                        pointRadius: 4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    scales: {
                        y: {
                            beginAtZero: true,
                            title: {
                                display: true,
                                text: '请求数量'
                            }
                        },
                        x: {
                            title: {
                                display: true,
                                text: '时间 (小时)'
                            }
                        }
                    }
                }
            });
        }

        // 更新表格
        function updateTables(analysisData) {
            updateIPTable(analysisData.topIPs, analysisData.basicStats.totalRequests);
            updateUserAgentTable(analysisData.topUserAgents, analysisData.basicStats.totalRequests);
            updatePathTable(analysisData.topPaths, analysisData.basicStats.totalRequests);
        }

        // 更新IP表格
        function updateIPTable(ips, totalRequests) {
            const tbody = document.getElementById('ipTableBody');
            
            if (!ips || ips.length === 0) {
                tbody.innerHTML = '<tr><td colspan="3" style="text-align: center; color: #6c757d;">暂无数据</td></tr>';
                return;
            }

            tbody.innerHTML = ips.map(ip => {
                const percentage = ((ip.count / totalRequests) * 100).toFixed(2);
                return `
                    <tr>
                        <td>${ip.ip}</td>
                        <td>${ip.count.toLocaleString()}</td>
                        <td>${percentage}%</td>
                    </tr>
                `;
            }).join('');
        }

        // 更新User Agent表格
        function updateUserAgentTable(userAgents, totalRequests) {
            const tbody = document.getElementById('userAgentTableBody');
            
            if (!userAgents || userAgents.length === 0) {
                tbody.innerHTML = '<tr><td colspan="3" style="text-align: center; color: #6c757d;">暂无数据</td></tr>';
                return;
            }

            tbody.innerHTML = userAgents.map(ua => {
                const percentage = ((ua.count / totalRequests) * 100).toFixed(2);
                return `
                    <tr>
                        <td title="${ua.ua}">${truncateText(ua.ua, 40)}</td>
                        <td>${ua.count.toLocaleString()}</td>
                        <td>${percentage}%</td>
                    </tr>
                `;
            }).join('');
        }

        // 更新路径表格
        function updatePathTable(paths, totalRequests) {
            const tbody = document.getElementById('pathTableBody');
            
            if (!paths || paths.length === 0) {
                tbody.innerHTML = '<tr><td colspan="4" style="text-align: center; color: #6c757d;">暂无数据</td></tr>';
                return;
            }

            tbody.innerHTML = paths.map(path => {
                const percentage = ((path.count / totalRequests) * 100).toFixed(2);
                const mainMethod = path.methods ? Object.keys(path.methods).reduce((a, b) => 
                    path.methods[a] > path.methods[b] ? a : b
                ) : 'GET';
                
                return `
                    <tr>
                        <td title="${path.path}">${truncateText(path.path, 50)}</td>
                        <td>${path.count.toLocaleString()}</td>
                        <td>${mainMethod}</td>
                        <td>${percentage}%</td>
                    </tr>
                `;
            }).join('');
        }

        // 工具函数
        function truncateText(text, maxLength) {
            return text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
        }

        function showLoading(show, message = '') {
            elements.loading.style.display = show ? 'block' : 'none';
            elements.loadingDetail.textContent = message;
        }

        function showError(message) {
            elements.uploadStatus.innerHTML = `<div class="error">${message}</div>`;
            setTimeout(() => {
                elements.uploadStatus.innerHTML = '';
            }, 5000);
        }

        function showSuccess(message) {
            elements.uploadStatus.innerHTML = `<div class="success">${message}</div>`;
            setTimeout(() => {
                elements.uploadStatus.innerHTML = '';
            }, 3000);
        }

        function showDashboard() {
            elements.dashboard.style.display = 'block';
        }

        function clearAllResults() {
            if (!confirm('确定要清空所有分析记录吗？此操作不可恢复。')) {
                return;
            }

            // 这里需要后端支持批量删除，暂时前端清空
            state.results = [];
            state.currentResult = null;
            renderResultsList();
            elements.dashboard.style.display = 'none';
            elements.exportBtn.disabled = true;
            elements.deleteBtn.disabled = true;
        }

        async function deleteCurrentResult() {
            if (!state.currentResult) return;

            if (!confirm(`确定要删除分析记录 "${state.currentResult.filename}" 吗？`)) {
                return;
            }

            try {
                const response = await fetch(`${CONFIG.API_BASE}/results/${state.currentResult.id}`, {
                    method: 'DELETE'
                });

                if (response.ok) {
                    showSuccess('删除成功');
                    await loadResults();
                    elements.dashboard.style.display = 'none';
                    elements.exportBtn.disabled = true;
                    elements.deleteBtn.disabled = true;
                } else {
                    throw new Error('删除失败');
                }
            } catch (error) {
                showError(`删除失败: ${error.message}`);
            }
        }

        function exportReport() {
            if (!state.currentResult) return;

            const report = generateTextReport();
            const blob = new Blob([report], { type: 'text/plain;charset=utf-8' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `pcap-analysis-${state.currentResult.id}.txt`;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }

        function generateTextReport() {
            if (!state.currentResult) return '';

            const analysis = state.currentResult.analysis;
            let report = 'PCAP流量分析报告\n';
            report += '='.repeat(50) + '\n\n';
            
            report += `文件名称: ${state.currentResult.filename}\n`;
            report += `分析时间: ${new Date(state.currentResult.uploadTime).toLocaleString()}\n`;
            report += `时间范围: ${analysis.basicStats.timeRange.start ? new Date(analysis.basicStats.timeRange.start).toLocaleString() : 'N/A'} - ${analysis.basicStats.timeRange.end ? new Date(analysis.basicStats.timeRange.end).toLocaleString() : 'N/A'}\n\n`;
            
            report += '基础统计:\n';
            report += `  总数据包: ${analysis.basicStats.totalPackets?.toLocaleString() || '0'}\n`;
            report += `  HTTP请求: ${analysis.basicStats.totalRequests?.toLocaleString() || '0'}\n`;
            report += `  独立IP数: ${Object.keys(analysis.clientIPs || {}).length}\n\n`;
            
            report += '请求方法分布:\n';
            Object.entries(analysis.methods || {}).forEach(([method, count]) => {
                const percentage = ((count / analysis.basicStats.totalRequests) * 100).toFixed(2);
                report += `  ${method}: ${count} (${percentage}%)\n`;
            });
            
            report += '\n状态码分布:\n';
            Object.entries(analysis.statusCodes || {}).forEach(([code, count]) => {
                const percentage = ((count / analysis.basicStats.totalRequests) * 100).toFixed(2);
                report += `  ${code}: ${count} (${percentage}%)\n`;
            });
            
            report += '\n热门请求路径:\n';
            (analysis.topPaths || []).slice(0, 10).forEach(path => {
                const percentage = ((path.count / analysis.basicStats.totalRequests) * 100).toFixed(2);
                report += `  ${path.path}: ${path.count} (${percentage}%)\n`;
            });
            
            return report;
        }
    </script>
</body>
</html>